#include"person.h"
#include"stdio.h"
#include<stdlib.h>
#include<string.h>
FILE * fptr = NULL;

void openFile(char * fileName,char * method){

    fptr = fopen(fileName,method);
    if(NULL == fptr){

        printf("open file %s failed.\n",fileName);
        return;
    }
}

void closeFile(){

    if(NULL != fptr){
        printf("close file.\n");
        fclose(fptr);
    }
}

PersonDatabase * Person_read(char * fileName){

    openFile(fileName,"r");
    if(NULL == fptr){

        return NULL;
    }
    PersonDatabase * perdb = malloc(sizeof(PersonDatabase));
    if(NULL == perdb){

        closeFile(fptr);
        return NULL;
    }
    // 输出文件中的人数
    int numPerson = 0;
    int longestName = 0;
    while(!feof(fptr)){

        int age;
        if(fscanf(fptr,"%d",&age) == 1){

            numPerson++;
            int nameLength = 0;
            while((!feof(fptr)) && (fgetc(fptr)!='\n')){

                nameLength++;
            }
            nameLength++;   // for '\n'
            if(longestName < nameLength) longestName = nameLength;
        }
    }
    // 人数数量和名字最长 已经读取到内存当中
    perdb->number = numPerson;
    perdb->person = malloc(sizeof(Person*)*numPerson);
    char * name = malloc(sizeof(char) * longestName);

    fseek(fptr,0,SEEK_SET);
    int ind = 0;
    while(!feof(fptr)){

        int age;
        if(fscanf(fptr,"%d",&age) == 1){

            // 去除年龄和名字之间的空格
            fgetc(fptr);
            fgets(name,longestName,fptr);
            char * chptr = strchr(name,'\n');   //  查找字符
            // 最后一行可能没有\n
            if(NULL != chptr){

                *chptr = '\0';
            }
            perdb->person[ind] = malloc(sizeof(Person));
            perdb->person[ind]->age = age;
            // strdup 自动调用malloc来分配内存
            perdb->person[ind]->name = strdup(name);
            ind++;
        }
    }
    free(name);
    closeFile();
    return perdb;
}
// 比较name 辅助函数
static int compareByName(const void * p1,const void * p2){

    const Person ** pp1 = (const Person **)p1;
    const Person ** pp2 = (const Person **)p1;

    const Person * const pv1 = *pp1;
    const Person * const pv2 = *pp2;

    return strcmp(pv1->name,pv2->name);
}

void Person_sortByName(PersonDatabase * perdb){

    qsort(perdb->person,perdb->number,sizeof(Person*),compareByName);
}

// 比较年龄辅助函数
static int compareByAge(const void * p1,const void * p2){

    const Person ** pp1 = (const Person **)p1;
    const Person ** pp2 = (const Person **)p2;

    const Person * const pv1 = *pp1;
    const Person * const pv2 = *pp2;

    return (pv1->age >= pv2->age);
}

void Person_sortByAge(PersonDatabase * perdb){

    qsort(perdb->person,perdb->number,sizeof(Person*),compareByAge);
}

static void Person_writeHelp(FILE * fptr,PersonDatabase * perdb){

    for(int index = 0;index < perdb->number;index++){

        fprintf(fptr,"%d %s\n",perdb->person[index]->age,perdb->person[index]->name);
    }
}

int Person_write(char * fileName,PersonDatabase * perdb){

    if(NULL == perdb || NULL == fileName){

        return 0;
    }
    openFile(fileName,"w");
    if(NULL == fptr){

        return 0;
    }
    Person_writeHelp(fptr,perdb);

    closeFile(fptr);

    return 1;
}
void Person_print(PersonDatabase * perdb){

    Person_writeHelp(stdout,perdb);
}

void Person_destruct(PersonDatabase * perdb){

    for(int index = 0;index < perdb->number;index++){

        free(perdb->person[index]->name);
        free(perdb->person[index]);
    }
    // 重复释放
    free(perdb->person);
    free(perdb);
}

int main(int argc,char * argv[]){


    if(argc < 4){


        return -1;
    }
    PersonDatabase * perdb = Person_read(argv[1]);
    if(NULL == perdb){

        printf("perdb is null.\n");
        return -1;
    }
    Person_print(perdb);
    Person_sortByName(perdb);
    if(Person_write(argv[2],perdb) == 0){

        Person_destruct(perdb);
        return -1;
    }
    Person_sortByAge(perdb);
    if(Person_write(argv[3],perdb) == 0){

        Person_destruct(perdb);
        return -1;
    }
    Person_destruct(perdb);
    return 0;
}